extends Node3D

var max_look_angle = 89.0

@onready var ray: RayCast3D = $RayCast3D
@onready var indicator: MeshInstance3D = $"../Indicator"

@export var move_speed: float = 10.0
@export var color: Color
@export var terrain: VoxelTerrain

var _mouse_motion: Vector2 = Vector2.ZERO
var _ray_point: Vector3
var _ray_normal: Vector3
var _target_block

signal color_changed(c: Color)

func set_color(c: Color) -> void:
	color = c
	color_changed.emit(c)


func _process(delta: float) -> void:
	_mouse_motion.y = clamp(_mouse_motion.y, -160, 160)
	transform.basis = Basis.from_euler(Vector3(_mouse_motion.y * -0.01, _mouse_motion.x * -0.01, 0))
	
	var dir := Input.get_vector(&"left", &"right", &"forward", &"back")
	var vert := Input.get_axis(&"down", &"up")
	
	position += move_speed * delta * (dir.y * transform.basis.z + dir.x * transform.basis.x + vert * Vector3.UP)
	
	if ray.is_colliding():
		_ray_point = ray.get_collision_point()
		_ray_normal = ray.get_collision_normal()
		_target_block = Vector3i((_ray_point - _ray_normal / 2).floor())
		indicator.global_position = Vector3(_target_block) + Vector3(0.5, 0.5, 0.5) + 0.01 * (global_position - indicator.global_position).normalized()
		indicator.show()
	else:
		_target_block = null
		indicator.hide()

func _physics_process(delta: float) -> void:
	var chunk_pos := Vector3i((position.floor() / 16.0).floor())
	chunk_pos.y = 0
	terrain.get_chunk(chunk_pos)
	
	if _target_block != null:
		var primary = Input.is_action_just_pressed(&"primary")
		var secondary = Input.is_action_just_pressed(&"secondary")
		if primary and secondary:
			terrain.set_voxel(_target_block, color)
		elif primary:
			terrain.remove_voxel(_target_block)
		elif secondary:
			var block := Vector3i((_ray_point + _ray_normal / 2).floor())
			terrain.set_voxel(block, color)


func _input(event: InputEvent) -> void:
	if Input.mouse_mode != Input.MOUSE_MODE_CAPTURED:
		return
	
	if event is InputEventMouseMotion:
		_mouse_motion += event.relative
		
	elif event.is_action_pressed(&"pick"):
		if _target_block != null:
			var voxel = terrain.get_voxel(_target_block)
			if voxel is Color:
				set_color(voxel)
	elif event.is_action_pressed(&"screenshot"):
		var image := get_viewport().get_texture().get_image()
		image.save_png("user://screenshot.png")
		print("Screenshot taked: ", ProjectSettings.globalize_path("user://screenshot.png"))
